package top.yangyitao.lockManager.lock.manager;

import top.yangyitao.lockManager.lock.LockManager;
import top.yangyitao.lockManager.lock.LockSubject;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author eetal
 */
public abstract class ThreadLocalLockManager implements LockManager<Object, LockSubject> {
    private static ThreadLocal<Set<LockSubject>> lockSet_TLS = new ThreadLocal<Set<LockSubject>>() {
        @Override
        protected Set<LockSubject> initialValue() {
            return new HashSet<LockSubject>();
        }
    };

    protected Set<LockSubject> getLockSet(){
        return lockSet_TLS.get();
    }

    @Override
    public List<LockSubject> search(Object obj) {
        List<LockSubject> result = new ArrayList<>();
        getLockSet().forEach(lock->{
            if(lock.equalKey(obj)){
                result.add(lock);
            }
        });
        return result;
    }

    @Override
    public boolean retire(LockSubject subject) {
        if(getLockSet().contains(subject)) {
            getLockSet().remove(subject);
            if (subject.isAlive()) {
                while (subject.isHeldByCurrentThread()) {
                    subject.unlock();
                }
                subject.destroy();
            }
            return true;
        }
        else {
            return false;
        }
    }

    @Override
    public void retireAll() {
        getLockSet().forEach(subject -> {
            if (subject.isAlive()) {
                while (subject.isHeldByCurrentThread()) {
                    subject.unlock();
                }
                subject.destroy();
            }
        });
        getLockSet().clear();
    }
}
